﻿#ifndef RTMPPUSHER_H
#define RTMPPUSHER_H

#include <QThread>
#include <QDebug>
#include <QMutexLocker>
#include "ffmpegheader.h"
#include "librtmp/rtmp.h"
#include "rtmpmsg.h"

enum AVPacketType
{
    TypeAudio = 0,
    TypeVideo
};

enum
{
    FLV_CODECID_H264 = 7,
    FLV_CODECID_AAC = 10,
};

struct ReadyPacket
{
    //AVpacket数据、类型、以及时间戳ms
    AVPacketType type;
    AVPacket *packet;
    uint32_t ptsTime;
    uint32_t dtsTime;
};

class RtmpPusher : public QThread
{
    Q_OBJECT
public:
    RtmpPusher();
    ~RtmpPusher();

    void setRunState(bool start);

    //测试推送本地flv文件
    void testPushFlvFile();

    //初始化发送队列
    void initSender();
    //释放队列
    void release();
    //音视频包的写入
    void writePacket(ReadyPacket *packet);

    //音视频头信息
    void setMetaMsg(FLVMetadataMsg *metaMsg);
    void setAudioSeqHeader(char *aacSeqHeader, int aacSeqHeaderLen);
    void setVideoSeqHeader(char *avcSeqHeader, int avcSeqHeaderLen);

    //解析AVPacket数据
    void parseVideoAVPacket(char *packetData, int packetSize, uint32_t ptsTime, uint32_t dtsTime);
    void parseAudioAVPacket(char *packetData, int packetSize, uint32_t ptsTime);

    //构造rtmp消息
    bool sendMetadata(FLVMetadataMsg *metadata);
    bool sendAACSpecificConfig();
    bool sendH264SequenceHeader();
    bool sendAACRawData(char *rawData, int size, uint32_t ptsTime);
    bool sendH264RawData(char *rawData, int size, uint32_t ptsTime, uint32_t dtsTime);

    //实际发送函数 内部分解rtmp消息chunk发送
    int sendRtmpPacket(int packetType, uint8_t *data, int size, uint32_t timeStamp);

protected:
    void run();

public:
    volatile bool isRun;
    QString filePath;
    uint32_t pushStartTime;

    RTMP *rtmp;
    bool hasAudio;
    bool hasVideo;

    QMutex mutex;

    //meta记录
    FLVMetadataMsg *metaMsg;

    //音频 AAC Sequence header
    char *aacSeqHeader;
    int aacSeqHeaderLen;
    //视频 AVC Sequence header
    char *avcSeqHeader;
    int avcSeqHeaderLen;

    //音视频包队列
    QList<ReadyPacket *> packetList;
};

#endif // RTMPPUSHER_H
